import { Injectable, Logger } from '@nestjs/common';
import * as puppeteer from 'puppeteer';
import {
  ICrawler,
  NovelInfo,
  ChapterInfo,
  ChapterContent,
} from '../interfaces/crawler.interface';

@Injectable()
export class QidianCrawlerV2 implements ICrawler {
  private readonly logger = new Logger(QidianCrawlerV2.name);
  private browser: puppeteer.Browser;

  async initBrowser() {
    if (!this.browser) {
      const executablePath =
        process.env.CHROME_EXECUTABLE_PATH ||
        'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';

      this.browser = await puppeteer.launch({
        headless: true,
        executablePath,
        args: [
          '--no-sandbox',
          '--disable-setuid-sandbox',
          '--disable-web-security',
          '--disable-blink-features=AutomationControlled',
        ],
      });
    }
  }

  getSource(): string {
    return 'qidian';
  }

  validateUrl(url: string): boolean {
    return url.includes('qidian.com');
  }

  async getNovelInfo(url: string): Promise<NovelInfo> {
    await this.initBrowser();
    const page = await this.browser.newPage();

    try {
      // 设置更真实的浏览器特征
      await page.setUserAgent(
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
      );
      await page.setViewport({ width: 1920, height: 1080 });

      // 移除webdriver标识
      await page.evaluateOnNewDocument(() => {
        Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined,
        });
      });

      this.logger.log(`开始访问起点页面: ${url}`);
      await page.goto(url, {
        waitUntil: 'domcontentloaded',
        timeout: 30000,
      });

      // 等待页面加载
      await new Promise((resolve) => setTimeout(resolve, 5000));

      // 提取小说基本信息
      const novelInfo = await page.evaluate(() => {
        const result = {
          title: '',
          author: '',
          cover: '',
          description: '',
          category: '',
          wordCount: '',
          status: 0,
          updateTime: '',
          chapterList: [] as any[],
        };

        // 获取标题 - 使用更广泛的选择器
        const titleSelectors = [
          '.book-info__title',
          'h1.book-name',
          '.book-name',
          'h1',
          '.title',
          '.book-title',
          '[class*="title"]',
          '.name',
        ];

        for (const selector of titleSelectors) {
          const element = document.querySelector(selector);
          if (
            element &&
            element.textContent &&
            element.textContent.trim().length > 0
          ) {
            result.title = element.textContent.trim();
            break;
          }
        }

        // 获取作者
        const authorSelectors = [
          '.book-info__author__name',
          '.author',
          '.book-author',
          '[class*="author"]',
          'a[href*="author"]',
          '.writer',
        ];

        for (const selector of authorSelectors) {
          const element = document.querySelector(selector);
          if (
            element &&
            element.textContent &&
            element.textContent.trim().length > 0
          ) {
            let authorText = element.textContent.trim();
            // 移除"作者"等前缀
            authorText = authorText.replace(/^作者[:：]\s*/, '');
            if (authorText.length > 0 && authorText.length < 20) {
              result.author = authorText;
              break;
            }
          }
        }

        // 获取封面
        const coverSelectors = [
          '.book-info__cover img',
          '.book-cover img',
          '.cover img',
          'img[src*="cover"]',
          'img[alt*="封面"]',
        ];

        for (const selector of coverSelectors) {
          const element = document.querySelector(selector) as HTMLImageElement;
          if (element && element.src) {
            result.cover = element.src;
            break;
          }
        }

        // 获取简介
        const descSelectors = [
          '.book-info__intro',
          '.book-intro',
          '.intro',
          '.description',
          '[class*="intro"]',
          '[class*="desc"]',
        ];

        for (const selector of descSelectors) {
          const element = document.querySelector(selector);
          if (
            element &&
            element.textContent &&
            element.textContent.trim().length > 50
          ) {
            result.description = element.textContent.trim();
            break;
          }
        }

        // 获取分类、状态、字数等信息
        const infoElements = document.querySelectorAll(
          '.book-info__row li, .book-info-detail li, [class*="info"] li, .detail li',
        );

        infoElements.forEach((element) => {
          const text = element.textContent?.trim();
          if (!text) return;

          // 分类
          if (!result.category && text.includes('类') && text.length < 20) {
            result.category = text;
          }
          // 状态
          if (!result.status && text.includes('完结')) {
            result.status = 1;
          }
          // 字数
          if (!result.wordCount && text.includes('万') && text.includes('字')) {
            result.wordCount = text;
          }
          // 更新时间
          if (
            (!result.updateTime && text.includes('更新于')) ||
            /\d{4}-\d{2}-\d{2}/.test(text)
          ) {
            result.updateTime = text;
          }
        });

        // 如果没有找到基本信息，尝试从页面标题等其他地方获取
        if (!result.title) {
          result.title = document.title.replace('-起点中文网', '').trim();
        }

        return result;
      });

      this.logger.log(
        `起点基本信息提取结果: 标题="${novelInfo.title}", 作者="${novelInfo.author}"`,
      );

      // 获取章节列表
      let chapters: ChapterInfo[] = [];

      // 首先尝试在当前页面查找章节链接
      chapters = await this.extractChaptersFromPage(page);

      // 如果当前页面没有章节，尝试跳转到目录页面
      if (chapters.length === 0) {
        chapters = await this.extractChaptersFromCatalog(page, url);
      }

      this.logger.log(`起点章节提取结果: 找到${chapters.length}个章节`);

      // 构建最终返回对象
      const finalNovelInfo: NovelInfo = {
        title: novelInfo.title || '未知标题',
        author: novelInfo.author || '未知作者',
        cover: novelInfo.cover || '',
        description: novelInfo.description || '',
        category: novelInfo.category || '其他',
        wordCount: novelInfo.wordCount || '',
        status: novelInfo.status,
        updateTime: novelInfo.updateTime || '',
        chapterList: chapters.slice(0, 50), // 限制章节数量
      };

      return finalNovelInfo;
    } catch (error) {
      this.logger.error(`解析起点小说失败: ${error.message}`, error.stack);
      throw new Error('解析起点小说失败');
    } finally {
      await page.close();
    }
  }

  private async extractChaptersFromPage(
    page: puppeteer.Page,
  ): Promise<ChapterInfo[]> {
    try {
      return await page.evaluate(() => {
        const chapters: ChapterInfo[] = [];

        // 查找章节链接的多种选择器
        const chapterSelectors = [
          'a[href*="chapter"]',
          'a[href*="/read/"]',
          '.chapter-item a',
          '.chapter a',
          '[class*="chapter"] a',
        ];

        for (const selector of chapterSelectors) {
          const elements = document.querySelectorAll(selector);
          if (elements.length > 0) {
            elements.forEach((element, index) => {
              const title = element.textContent?.trim();
              const href = (element as HTMLAnchorElement).href;

              if (title && href && title.includes('第')) {
                chapters.push({
                  title,
                  url: href,
                  index: index + 1,
                  isFree: true, // 默认免费，具体需要进一步判断
                  content: '',
                  volumeName: '正文',
                });
              }
            });
            break; // 找到章节后停止尝试其他选择器
          }
        }

        return chapters;
      });
    } catch (error) {
      this.logger.warn(`从页面提取章节失败: ${error.message}`);
      return [];
    }
  }

  private async extractChaptersFromCatalog(
    page: puppeteer.Page,
    originalUrl: string,
  ): Promise<ChapterInfo[]> {
    try {
      // 从URL提取书籍ID
      const bookIdMatch = originalUrl.match(/\/(\d+)/);
      if (!bookIdMatch) {
        this.logger.warn('无法从URL提取书籍ID');
        return [];
      }

      const bookId = bookIdMatch[1];
      const catalogUrl = `https://www.qidian.com/book/${bookId}/catalog`;

      this.logger.log(`尝试访问目录页面: ${catalogUrl}`);

      await page.goto(catalogUrl, {
        waitUntil: 'domcontentloaded',
        timeout: 30000,
      });

      await new Promise((resolve) => setTimeout(resolve, 3000));

      return await page.evaluate(() => {
        const chapters: ChapterInfo[] = [];

        // 查找卷名
        const volumeElements = document.querySelectorAll(
          '.volume-wrap, .volume, [class*="volume"]',
        );
        let currentVolumeName = '正文';

        volumeElements.forEach((volumeElement) => {
          const volumeNameElement = volumeElement.querySelector(
            '.volume-name, [class*="volume-name"]',
          );
          if (volumeNameElement && volumeNameElement.textContent) {
            currentVolumeName = volumeNameElement.textContent.trim();
          }

          // 在该卷下查找章节
          const chapterElements = volumeElement.querySelectorAll(
            'a[href*="chapter"], .chapter-item a, [class*="chapter"] a',
          );

          chapterElements.forEach((element, index) => {
            const title = element.textContent?.trim();
            const href = (element as HTMLAnchorElement).href;

            if (title && href && title.includes('第')) {
              chapters.push({
                title,
                url: href,
                index: chapters.length + 1,
                isFree: true, // 默认免费
                content: '',
                volumeName: currentVolumeName,
              });
            }
          });
        });

        // 如果没有找到卷结构，尝试直接查找章节
        if (chapters.length === 0) {
          const directChapterElements = document.querySelectorAll(
            'a[href*="chapter"], a[href*="/read/"]',
          );

          directChapterElements.forEach((element, index) => {
            const title = element.textContent?.trim();
            const href = (element as HTMLAnchorElement).href;

            if (title && href && title.includes('第')) {
              chapters.push({
                title,
                url: href,
                index: index + 1,
                isFree: true,
                content: '',
                volumeName: '正文',
              });
            }
          });
        }

        return chapters;
      });
    } catch (error) {
      this.logger.error(`从目录页面提取章节失败: ${error.message}`);
      return [];
    }
  }

  async getChapterContent(chapterUrl: string): Promise<ChapterContent> {
    await this.initBrowser();
    const page = await this.browser.newPage();

    try {
      await page.setUserAgent(
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
      );
      await page.goto(chapterUrl, { waitUntil: 'domcontentloaded' });

      const content = await page.evaluate(() => {
        const title =
          document
            .querySelector('h1, .chapter-title, [class*="title"]')
            ?.textContent?.trim() || '';

        // 尝试多种内容选择器
        const contentSelectors = [
          '.chapter-content',
          '.content',
          '[class*="content"]',
          '.text',
          '[class*="text"]',
        ];

        let content = '';
        for (const selector of contentSelectors) {
          const element = document.querySelector(selector);
          if (element && element.textContent) {
            content = element.textContent.trim();
            if (content.length > 100) break;
          }
        }

        return { title, content };
      });

      return {
        title: content.title,
        content: content.content,
        index: 0,
      };
    } finally {
      await page.close();
    }
  }

  async onModuleDestroy() {
    if (this.browser) {
      await this.browser.close();
    }
  }
}
